#include "CloudProtocol.h"

CloudProtocol::CloudProtocol(QObject *parent) :
    BaseProtocol(parent)
{
    this->m_protocolType = ProtocolType::CloudProtocol;
}

QList<Package> CloudProtocol::parseData(QByteArray data)
{
    quint8  checkSteps = CHECK_HEAD;          //当前解析状态
    quint16 lengthCount;                 //数据长度计算
    quint8  headNum=0;                    //数据头索引计算
    quint16 bodyLength;
    QByteArray dataArray;
    quint16 crc16=0;
    QList<Package> packageList;
    //qDebug()<<"CloudCMD cheaking now----------------------";
    for(int i=0; i<data.size(); i++)
    {
        quint8 byte = data.at(i);
        switch(checkSteps)
        {
            case CHECK_HEAD:   //检查数据头
                 if(byte == 0xF0 && headNum == 0)
                 {
                     headNum++;
                 }
                 if(byte == 0x0F && headNum == 1)
                 {
                    headNum=0;
                    lengthCount = 0;
                    bodyLength = 0;
                    dataArray.clear();
                    dataArray.append(0xF0);
                    dataArray.append(0x0F);
                    checkSteps = CHECK_VERSION;
                 }
            break;

            case CHECK_VERSION:
                 checkSteps = CHECK_ID;
                 dataArray.append(byte);
                 break;

            case CHECK_ID:
                 lengthCount++;
                 dataArray.append(byte);
                 if(lengthCount == 2)
                 {
                     lengthCount = 0;
                     checkSteps = CHECK_FUNCTION;
                 }
                 break;

            case CHECK_FUNCTION:   //接收数据功能
                 dataArray.append(byte);
                 checkSteps = CHECK_LENGTH;
            break;

            case CHECK_LENGTH:
                 lengthCount++;
                 dataArray.append(byte);
                 if(lengthCount == 1)
                 {
                     bodyLength = (quint16)byte << 8;
                 }
                 if(lengthCount == 2)
                 {
                     lengthCount = 0;
                     bodyLength |= byte;
                     if(bodyLength == 0)
                     {
                         checkSteps = CHECK_CHECKCODE;
                     }
                     else
                     {
                         checkSteps = CHECK_BODY;
                     }
                 }
                 break;

            case CHECK_BODY:    //接收数据
                 lengthCount++;
                 dataArray.append(byte);
                 if(lengthCount >= bodyLength)
                 {
                     lengthCount = 0;
                     checkSteps = CHECK_CHECKCODE;
                 }
                 break;

            case CHECK_CHECKCODE:
                 lengthCount++;
                 dataArray.append(byte);
                 if(lengthCount == 1)
                 {
                     crc16 = quint16(byte)<<8;
                 }
                 if(lengthCount == 2)
                 {
                     lengthCount = 0;
                     crc16 |= byte;
                     if(CheckCode::computeCRC16(dataArray,dataArray.size()-2) == crc16)
                     {
                         Package package;
                         package.setHead(dataArray.mid(0,2));
                         package.setVersion(dataArray.mid(2,1).toHex().toInt(0,16));
                         package.setId(dataArray.mid(3,2).toHex().toInt(0,16));
                         package.setFunction(dataArray.mid(5,1).toHex().toInt(0,16));
                         package.setLength(dataArray.mid(6,2).toHex().toInt(0,16));
                         package.setBody(dataArray.mid(8,bodyLength));
                         package.setCheckCode(dataArray.mid(8+bodyLength,2).toHex().toInt(0,16));
                         packageList.append(package);
                    //     qDebug()<<"cmdbody="<<DataTypeConver::formatString(package.body());
                     }
                     checkSteps = CHECK_HEAD;
                 }
        }
    }

    return packageList;
}

QByteArray CloudProtocol::generateData(Package package)
{

    QByteArray head = QByteArray::fromHex(QString("F00F").toLatin1());
    quint8 version  = 2;
    quint16 length  = package.body().length();

    package.setHead(head);
    package.setVersion(version);
    package.setLength(length);

    QByteArray data;
    data.append(package.head());
    data.append(package.version());
    data.append(DataTypeConver::intToByteArray(package.id(),2));
    data.append(package.function());
    data.append(DataTypeConver::intToByteArray(package.length(),2));
    data.append(package.body());

    quint16 crc16 = CheckCode::computeCRC16(data,data.size());
    data.append(DataTypeConver::intToByteArray(crc16,2));

    return data;
}
